/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package stateful;

import entities.Conversation;
import entities.Loggedin;
import entities.Message;
import entities.User;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateful;
import javax.persistence.*;

/**
 *
 * @author oana.leva
 */
@Stateful
public class ChatSessionBean implements ChatSessionLocal {

    @PersistenceContext
    EntityManager em;

    protected User loggedInUser = null;

    public void UpdateUserInfo(String newPwd, String newDescription)
    {
    }

    public void LogUserOut()
    {
        if (loggedInUser == null)
            return;

        //remove all the login entries for this user
        Collection <Loggedin> logEntries = loggedInUser.getLoggedinCollection();
        for (Loggedin l : logEntries)
        {
            if (l!=null)
            {
                em.remove(l);
            }
        }

        loggedInUser = null;
    }

    public boolean SignUserUp(String name, String pwd, String description)
    {
        try
        {
            //check for uniqueness:
            Query findByNameQuery = em.createNamedQuery("User.findByName");
            findByNameQuery.setParameter("name", name);
            if (!findByNameQuery.getResultList().isEmpty())
            {
                //we've already got (at least) one user by this name
                return false;
            }

            //create the new user:
            User chatUser = new User(0, name, pwd, description);
            //add the newly created user to the database:
            em.persist(chatUser);
            return true;
        }
        catch (Exception e)
        {
            Logger.getLogger(ChatSessionBean.class.getName()).log(Level.SEVERE, null, e);
        }
        return false;
    }

    public boolean LogUserIn(String name, String pwd) {
        try
        {
            Query query=em.createNamedQuery("User.findByName");//named query used in the bean class (added in the entity class: User.java)
            query.setParameter("name",name);
            User usr = (User)query.getSingleResult();

            boolean doesPassMatch = (usr.getPassword().trim().equals( pwd.trim()));
            if (doesPassMatch)
            {
                //set the logged in user
                loggedInUser = usr;

                //now add an entry in loggedin
                Loggedin logEntry = new Loggedin();

                //this sets the current date & time:
                logEntry.setLogindate(new Date());

                //set the current user
                logEntry.setUserid(loggedInUser);

                //the conversation will be null for now -> the user's not talking to anyone!

                //add the new log entry to the database:
                em.persist(logEntry);

                //TODO: test if this is needed:
                em.refresh(loggedInUser);
            }

            return doesPassMatch;
        }
        catch (Exception e)
        {
            Logger.getLogger(ChatSessionBean.class.getName()).log(Level.SEVERE, null, e);
        }        
        return false;
    }

    public List<User> GetLoggedInUsers()
    {
        List<User> users = null;        
        try
        {            
            Query query=em.createNamedQuery("Loggedin.getLoggedInUsers");
            users = query.getResultList();
        }
        catch (Exception e)
        {
            Logger.getLogger(ChatSessionBean.class.getName()).log(Level.SEVERE, null, e);
        }
        
        return users;
    }

    public boolean IsLoggedIn()
    {
        return loggedInUser != null;
    }

    protected Conversation CreateConversation (String conversationName)
    {
        if (!IsLoggedIn())
            return null;

        //check for duplicate conversation names:
        Query findByNameQuery = em.createNamedQuery("Conversation.findByName");
        findByNameQuery.setParameter("name", conversationName);
            if (!findByNameQuery.getResultList().isEmpty())
            {
                //we've already got (at least) one conversation by this name
                return null;
            }

        //create the conversation object:
        Conversation conv = new Conversation();
        conv.setName(conversationName);
        em.persist(conv);

        //when a user creates a conversation he's automatically logged into that conversation
        AddUserToConversation(loggedInUser, conv);
        
        return conv;
    }

    private void AddUserToConversation (User usr, Conversation conv)
    {
        Collection <Loggedin> logEntries = usr.getLoggedinCollection();
        if (logEntries.isEmpty())
        {
            //OOOPS! no login info??
            Logger.getLogger(ChatSessionBean.class.getName()).log(Level.SEVERE, "No loggedin entries for logged in user! -> logging in automatically");
            //the new Loggedin object will be created below and the conversation will be assigned to it
        }
        else if (logEntries.size() == 1)
        {
            //only one entry -> it may have no attached conversation
            Iterator it = logEntries.iterator();
            Loggedin l = (Loggedin) it.next();
            if (l.getConversationid() == null)
            {
                //it has no conversation attached -> create and add one
                l.setConversationid(conv);
                return;
            }
        }

        //if we got here we must create a new Loggedin entry and assign the conversation to it
        Loggedin l = new Loggedin();
        l.setUserid(usr);
        l.setLogindate(new Date());
        l.setConversationid(conv);
        em.persist(l);
    }

    public Conversation StartConversationWithUser(User otherUsr)
    {
        if ((!IsLoggedIn()) || (otherUsr == null) || (!otherUsr.isLoggedIn()))
            return null;

        String conversationName = "Dialogue"+loggedInUser.getName()+"+"+otherUsr.getName();
        Conversation conv = CreateConversation(conversationName);
        if (conv != null)
        {
            //ok, we've created the new conversation
            //it has only one member, the creator -> we must add the other user to the conversation
            AddUserToConversation(otherUsr, conv);
        }

        return conv;
    }

    public void PrintMessages(int conversationId, PrintWriter out)
    {
        try
        {
            Query query=em.createNamedQuery("Conversation.findById");//named query used in the bean class (added in the entity class: User.java)
            query.setParameter("id",conversationId);
            Conversation conv = (Conversation)query.getSingleResult();
            //we have the conversation, now let's see if our user is a member of it
            //TODO: check that (security issue)
            if (IsLoggedIn())
                conv.printMessages(out);
        }catch (Exception e)
        {
            Logger.getLogger(ChatSessionBean.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    public boolean PostMessage(int conversationId, String payLoad)
    {
        if (!IsLoggedIn())
            return false;

        try
        {
            Query query=em.createNamedQuery("Conversation.findById");//named query used in the bean class (added in the entity class: User.java)
            query.setParameter("id",conversationId);
            Conversation conv = (Conversation)query.getSingleResult();
            //we have the conversation, now let's see if our user is a member of it
            //TODO: check that (security issue)
            if (conv == null)
                return false;

            //create a new message
            Message msg = new Message();
            msg.setSenderid(loggedInUser);
            msg.setPayload(payLoad);
            msg.setConversationid(conv);
            em.persist(msg);
            return true;
        }catch (Exception e)
        {
            Logger.getLogger(ChatSessionBean.class.getName()).log(Level.SEVERE, null, e);
            return false;
        }

    }
    
    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method" or "Web Service > Add Operation")
    
}
